#include "distinctivenamesrule.h"

#include "../documents/data/graphicdata.h"
#include "../documents/swpprocessdocument.h"
#include "../editors/items/graphicitemcommon.h"

#include <gdmodelquerymaker.h>
#include <icontainerdocument.h>
#include <ieditoritem.h>

#include <QtGui/QAction>

using namespace core;
using namespace swp;

DistinctiveNamesRule::DistinctiveNamesRule() : IValidatorRule()
{

}

DistinctiveNamesRule::~DistinctiveNamesRule()
{

}

bool DistinctiveNamesRule::isProjectWide() const
{
    return true;
}

bool DistinctiveNamesRule::validate(
    const QSharedPointer<IContainerDocument>& document,
    QAction*& reportClickAction, QString& reportText) const
{
    bool ret = true;

    const QStringList categories = document->categories();

    QHash<QString, QSet<QString> > duplicates;

    foreach (const QString& category, categories)
    {
        duplicates[category] = QSet<QString>();

        QSet<QString> names;

        foreach (const QSharedPointer<IDocument> _document,
            document->documents(category))
        {
            GraphicData* data = dynamic_cast<GraphicData* >(
                _document->data());

            if(data != 0) // GraphicData expected
            {
                GDModelQueryMaker queryMaker(*data);

                const QList<IGraphicEditorItem* > items =
                    queryMaker.getItems();

                foreach (IGraphicEditorItem* item, items)
                {
                    QString propertyName;
                    bool shouldProcess = true;

                    switch (item->type())
                    {
                        case SWP_WORKER_ITEM:
                        case SWP_RESOURCE_ITEM:
                        case SWP_ARTIFACT_ITEM:
                        case SWP_STAKEHOLDER_ITEM:
                            propertyName = "class";
                            break;
                        case SWP_ACTIVITY_ITEM:
                            propertyName = "name";
                            break;
                        default:
                            shouldProcess = false;
                            break;
                    }

                    if (shouldProcess)
                    {
                        const QString name = item->propertyValue(
                            propertyName).toString();

                        if (names.contains(name))
                        {
                            if (!duplicates[category].contains(name))
                            {
                                duplicates[category].insert(name);
                            }

                            ret = false;
                        }
                        else
                        {
                            names.insert(name);
                        }
                    }
                }
            }
        }
    }

    QString detail;

    if (!ret)
    {
        foreach (const QString& category, duplicates.keys())
        {
            QStringList concreteDuplicates(duplicates[category].toList());

            if (!concreteDuplicates.isEmpty())
            {
                detail += QObject::tr(", in %1 category: [%2]").arg(
                    category).arg(concreteDuplicates.join(", "));
            }
        }
    }

    reportText = QObject::tr("Project contains duplicates %1").arg(detail);

    return ret;
}

bool DistinctiveNamesRule::validate(const QSharedPointer<IDocument>& document,
    QAction*& reportClickAction, QString& reportText) const
{
    return false;
}
